package fr.eisti.icc.data;

import fr.eisti.icc.data.service.BibliothequeRESTFacade;
import fr.eisti.icc.data.service.DocumentRESTFacade;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.codehaus.jackson.annotate.JsonIgnore;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author clion
 */
@Entity
@Table(name="BIBLIOTHEQUE")
@XmlRootElement
public class Bibliotheque implements Serializable {

    @Id
    @Column(name="id")
    private int id;
    @OneToMany(cascade=CascadeType.ALL)
    private List<Emprunteur> clients;
    @OneToMany(cascade=CascadeType.ALL)
    private List<Document> documents;

    private static Bibliotheque instance = null;

    //////////////////////////////////CONSTRUCTEURS//////////////////////////////////

    public Bibliotheque() {
    }

    private Bibliotheque(int id) {
        this.id = id;
    }

    public static Bibliotheque getInstance() {
        int identifiant = 1;
        if (instance == null) {          
            BibliothequeRESTFacade blf=new BibliothequeRESTFacade();
           // instance=blf.find(identifiant);
            
            if (instance == null) {
                synchronized (Bibliotheque.class) {
                    if (instance == null) {
                        instance = new Bibliotheque(identifiant);
                        instance.setClients(new ArrayList<Emprunteur>());
                        instance.setDocuments(new ArrayList<Document>());
                        blf.create(instance);
                        System.out.println("rr");
                    }
                }
            }
        }
        return instance;
    }

    //////////////////////////////////GETTERS+SETTERS//////////////////////////////////

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @XmlTransient
    @JsonIgnore
    public List<Emprunteur> getClients() {
        return clients;
    }

    public void setClients(List<Emprunteur> clients) {
        this.clients = clients;
    }

    @XmlTransient
    @JsonIgnore
    public List<Document> getDocuments() {
        return documents;
    }

    public void setDocuments(List<Document> documents) {
        this.documents = documents;
    }


    //////////////////////////////////fONCTIONS//////////////////////////////////


    public static boolean ajouterDocument(Document doc) {
DocumentRESTFacade docrf=new DocumentRESTFacade();
docrf.create(doc);
        return getInstance().documents.add(doc);
    }

    public static boolean supprimerLivre(Document doc) {
        return getInstance().documents.remove(doc);
    }

    public static boolean miseAJourLivre(Document doc) {

        for (int i = 0; i < getInstance().documents.size(); i++) {
            if (getInstance().documents.get(i).getId() == doc.getId()) {
                if (getInstance().documents.remove(doc)) {
                    return ajouterDocument(doc);
                } else {
                    return false;
                }
            }

        }
        return false;

    }

    public static <Type> List<Document> getAllDocuments(DocumentType type) {
        List<Document> docs = new ArrayList();
        for (int i = 0; i < getInstance().documents.size(); i++) {
            if (getInstance().documents.get(i).getClass().isAssignableFrom(type.getValue())) {

                docs.add(getInstance().documents.get(i));
            }
        }
        return docs;
    }

    public static <Type> List<Document> getDocuments(DocumentType type, Filtre filtre) {
        List<Document> docs = new ArrayList();
        for (int i = 0; i < getInstance().documents.size(); i++) {
            if (getInstance().documents.get(i).getClass().isAssignableFrom(type.getValue()) && getInstance().documents.get(i).accept(filtre)) {

                docs.add(getInstance().documents.get(i));
            }
        }
        return docs;
    }

    public static Document getDocumentsById(int id) {
        Document doc = null;
        for (int i = 0; i < getInstance().documents.size(); i++) {
            if (getInstance().documents.get(i).getId() == id) {

                doc = getInstance().documents.get(i);
            }
        }
        return doc;
    }

    public static Emprunteur getClientById(int id) {
        Emprunteur doc = null;
        for (int i = 0; i < getInstance().clients.size(); i++) {
            if (getInstance().clients.get(i).getId() == id) {

                doc = getInstance().clients.get(i);
            }
        }
        return doc;
    }
    public static List<Emprunteur> getClientBlackList() {
        List<Emprunteur> doc = new ArrayList();
        for (int i = 0; i < getInstance().clients.size(); i++) {
            if ( getInstance().clients.get(i).getEstBlackListe() == true) {

                doc.add(getInstance().clients.get(i));
            }
        }
        return doc;
    }
    public static Emprunteur getClientByName(String nom,String prenom) {
            Emprunteur doc = null;
            for (int i = 0; i < getInstance().clients.size(); i++) {
                if (getInstance().clients.get(i).getNom() == nom && getInstance().clients.get(i).getPrenom() == prenom ) {

                    doc = getInstance().clients.get(i);
                }
            }
            return doc;
        }

    public static boolean preterDocument(int idDocument, int idClient,Date debutEmprunt,boolean chequeCaution) {
        Document doc  = getDocumentsById(idDocument);
        Emprunteur cl = getClientById(idClient);
        int jours=15;
        if (cl instanceof Professeur){
            jours=150;
        }
        if (cl.peutEmprunter()){
            Emprunt emp=new Emprunt(doc, debutEmprunt, jours, chequeCaution);
            return cl.addEmprunt(emp);

        }
        return false;


    }
    public static boolean RecupererDocument(int idDocument, int idClient) {
        Document doc  = getDocumentsById(idDocument);
        Emprunteur cl = getClientById(idClient);
        return cl.removeEmprunt(doc);



    }

    public static boolean addClient(Emprunteur emp) {
        return getInstance().clients.add(emp);
    }

    public static boolean supprimerClient(Emprunteur emp) {
        return getInstance().documents.remove(emp);
    }

    public static void addBlackListClient(Emprunteur emp) {
        emp.setEstBlackListe(true);
    }

    public static void supprimerBlackListClient(Emprunteur emp) {
        emp.setEstBlackListe(false);
    }

    public static boolean isInLDAPDatabase(String login, String mdp) {
        return false;
    }

    public static void save() {
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
        Session session = sessionFactory.getCurrentSession();
        session.beginTransaction();
        Bibliotheque cours = (Bibliotheque) session.save(Bibliotheque.getInstance());
        session.close();
    }
}